//
//  Handy.swift
//  CooperSwift_Example
//
//  Created by 计海峰 on 2021/6/15.
//  Copyright © 2021 CocoaPods. All rights reserved.
//

import Foundation
import RxSwift
import HandyJSON

public enum ShowToastType {
    case all, error, none
}

public protocol ResultProtocol: HandyJSON {
    func toastMsg(_ tag: String?) -> String!
    func isSuccess() -> Bool
    // step 1
    func run(_ tag: String?) -> Void
    // step2
    func showToast(_ type: ShowToastType, tag: String?)
    // step3
    func result_data(_ tag: String?) -> Any?
}

public extension ResultProtocol {
    
    func toastMsg(_ tag: String?) -> String! {
        return ""
    }
    
    func showToast(_ type: ShowToastType, tag: String?) {
        guard let hint = self.toastMsg(tag), hint.count > 0 else { return }
        
    }
    
    func result_data(_ tag: String? = nil) -> Any? {
        return nil
    }
    
}

public extension Observable where Element : Any {
    
    /// 普通 Json 转 Model
    func mapHandyModel <T : HandyJSON> (type : T.Type) -> Observable<T?> {
        return self.map { (element) -> T? in
        
            /// 这里的data 是 String 或者 dic
            let data = element
            
            let parsedElement : T?
            if let string = data as? String {
                parsedElement = T.deserialize(from: string)
            } else if let dictionary = data as? Dictionary<String , Any> {
                parsedElement = T.deserialize(from: dictionary)
            } else if let dictionary = data as? [String : Any] {
                parsedElement = T.deserialize(from: dictionary)
            } else {
                parsedElement = nil
            }
            return parsedElement
        }
    }
    
    // 将 Json 转成 模型数组
    func mapHandyModelArray<T: HandyJSON>(type: T.Type) -> Observable<[T?]?> {
        return self.map { (element) -> [T?]? in
        
            /// 这里的data 是 String 或者 dic
            let data = element
            
            let parsedArray : [T?]?
            if let string = data as? String {
                parsedArray = [T].deserialize(from: string)
            } else if let array = data as? [Any] {
                parsedArray = [T].deserialize(from: array)
            } else {
                parsedArray = nil
            }
            return parsedArray
        }
    }
    
    
    // 将 Json 转成 模型数组 统一校验
    func mapHandyResultModel <T : ResultProtocol> (type : T.Type, toast: ShowToastType = .none, tag: String? = nil) -> Observable<Any?> {
        return self.map { (element) -> Any? in
            /// 这里的data 是 String 或者 dic
            let data = element
            
            let parsedElement : T?
            if let string = data as? String {
                parsedElement = T.deserialize(from: string)
            } else if let dictionary = data as? Dictionary<String , Any> {
                parsedElement = T.deserialize(from: dictionary)
            } else if let dictionary = data as? [String : Any] {
                parsedElement = T.deserialize(from: dictionary)
            } else {
                parsedElement = nil
            }
            if let result = parsedElement {
                result.run(tag)
                if toast != .none {
                    result.showToast(toast, tag: tag)
                }
            }
            return parsedElement?.result_data(tag)
        }
    }
    
}
